//
//  CHKFile.m
//  MapEdit
//
//  Created by Steven Canfield on 10/06/07.
//

#import "CHKFile.h"

@implementation CHKFile
- (id)initWithData:(NSData *)data {
	self = [super init];
	
	_savedData = [data copy];
	
	if( self != NULL ) {
		int dataIndex = 0;
		
		_chunkStorage		= [[NSMutableDictionary alloc] init];
		_chunkSaveCallbacks = [[NSMutableDictionary alloc] init];
		_chunkNames			= [[NSMutableArray alloc] init];

		while( dataIndex < [data length] ){
			u_int8_t name[5];
			name[4] = '\0';
			[data getBytes:&name range:NSMakeRange( dataIndex, 4 )];
			dataIndex += 4;
			u_int32_t numBytes;
			[data getBytes:&numBytes range:NSMakeRange( dataIndex, 4 )];
			numBytes = NSSwapLittleIntToHost( numBytes );
			dataIndex +=4 ;
			
			const char * name_string = (const char *)name;
			NSData * sectionData = [data subdataWithRange:NSMakeRange( dataIndex, numBytes )];
			NSString * cString = [[NSString alloc] initWithCString:name_string encoding:NSASCIIStringEncoding];
			[_chunkStorage setObject:sectionData forKey:cString];
			[_chunkNames addObject:cString];
			dataIndex += numBytes;
		}
	}
	return self;
}

- (NSData *)serialize {
	NSMutableData * data = [[NSMutableData alloc] init];
	
	int chunkNameIndex;
	for( chunkNameIndex = 0; chunkNameIndex < [_chunkNames count]; chunkNameIndex++ ) {
		NSString	 * chunkName = [_chunkNames objectAtIndex:chunkNameIndex];
		NSInvocation * invocation = [_chunkSaveCallbacks objectForKey:chunkName];
		NSData		 * pieceData;
		if( invocation == NULL ) {
			/* Nobody Registered to Save This */
			pieceData = [_chunkStorage objectForKey:chunkName];
			[data appendSectionNamed:[chunkName UTF8String] withBytes:(void *)[pieceData bytes] length:[pieceData length]];
		} else {
			[invocation invoke];
			[invocation getReturnValue:&pieceData];
			[data appendData:pieceData];
		}
	}
	return data;
}

- (NSData *)dataForChunkNamed:(NSString *)chunkName {
	return [_chunkStorage objectForKey:chunkName];
}

- (void)setSaveCallbackForChunkNamed:(NSString *)name target:(id)target selector:(SEL)sel {
	NSMethodSignature	* signature  = [CHKFile instanceMethodSignatureForSelector:@selector(dataCallbackExample)];
	NSInvocation		* invocation = [NSInvocation invocationWithMethodSignature:signature];
	[invocation retainArguments];
	[invocation setTarget:target];
	[invocation setSelector:sel];
	[_chunkSaveCallbacks setObject:invocation forKey:name]; 
}

- (NSData *)dataCallbackExample {
	/* Data Callback */
	return NULL;
}

@end
